package vista;

import fantasma.Fantasmas;
import interfaces.IFantasma;
import interfaces.IPacman;
import interfaces.IVista;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import laberinto.Casilla;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import xml.xmlUtilidades;

public class VisualizacionXMLDeEstadosDePersonajes implements IVista {

	private IPacman pacman;
	private Fantasmas fantasmas;
	private String rutaArchivoDestino;
	
	/**
	 * 
	 * @param pacman modelo a ser invocado por la vista
	 * @param fantasmas modelo a ser invocado por la vista
	 * @param rutaArchivoDestino
	 */
	public VisualizacionXMLDeEstadosDePersonajes(IPacman pacman,
			Fantasmas fantasmas, String rutaArchivoDestino) {
		this.pacman = pacman;
		this.fantasmas = fantasmas;
		this.rutaArchivoDestino = rutaArchivoDestino;
	}


	@Override
	public void actualizar(int iteracion) {
		exportarEstadosDePersonajes(rutaArchivoDestino,pacman,fantasmas,iteracion);
		
	}
	
	
private void exportarEstadosDePersonajes(String rutaArchivoDestino, IPacman pacman, Fantasmas fantasmas, int tick) {
		
		rutaArchivoDestino = xmlUtilidades.completarRuta(rutaArchivoDestino);
		rutaArchivoDestino = xmlUtilidades.completarNombreDeArchivo(rutaArchivoDestino, tick);
		try {

			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			Document xmlPersonajes = docBuilder.newDocument();
			Element nodoRaiz = xmlPersonajes.createElement("juego");
			xmlPersonajes.appendChild(nodoRaiz);

			if(pacman != null){
				Casilla casillaDelPacman = pacman.obtenerCasilla();

				nodoRaiz.setAttribute("posicionPacman", casillaDelPacman.obtenerIdCasilla());
				nodoRaiz.setAttribute("fila", String.format("%02d", casillaDelPacman.obtenerFila()));
				nodoRaiz.setAttribute("columna", String.format("%02d", casillaDelPacman.obtenerColumna()));
				nodoRaiz.setAttribute("sentido", pacman.obtenerDireccionEnTexto());
				nodoRaiz.setAttribute("puntaje", "0");
			
				if (pacman.estaMuerto())
					nodoRaiz.setAttribute("finJuego", "true");
				else nodoRaiz.setAttribute("finJuego", "false");
			}
			
			insertarFantasmas(xmlPersonajes, nodoRaiz, fantasmas);

			// Escribe el documento xml en un nuevo archivo
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();

			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

			DOMSource source = new DOMSource(xmlPersonajes);
			StreamResult result = new StreamResult(new File(rutaArchivoDestino));

			transformer.transform(source, result);

		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (TransformerException tfe) {
			tfe.printStackTrace();
		}
	}

	private void insertarFantasmas(Document doc, Element nodoRaiz, Fantasmas fantasmas) {
		
		int idFantasma = 1;
		
		for (IFantasma fantasma : fantasmas.obtenerArrayListDeFantasmas()){

			Element elementoFantasma = doc.createElement("fantasma");
			nodoRaiz.appendChild(elementoFantasma);

			Casilla casillaFantasma = fantasma.obtenerCasilla();
			
			elementoFantasma.setAttribute("id", Integer.toString(idFantasma));
			elementoFantasma.setAttribute("nodo", casillaFantasma.obtenerIdCasilla());
			elementoFantasma.setAttribute("fila", String.format("%02d", casillaFantasma.obtenerFila()));
			elementoFantasma.setAttribute("columna", String.format("%02d", casillaFantasma.obtenerColumna()));
			elementoFantasma.setAttribute("sentido", fantasma.obtenerSentido());
			elementoFantasma.setAttribute("personalidad", fantasma.obtenerPersonalidad());
			elementoFantasma.setAttribute("estado", fantasma.obtenerEstado());
			
			idFantasma++; 
		}

	}
	
}